home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 4
/
The Arsenal Files 4 (Arsenal Computer).ISO
/
casm
/
au116-as.exe
/
VERSION.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-13
|
15KB
|
675 lines
// VERSION.CPP 1 1 6666
// Dave Harris 11 11 6
// Compiled using Borland C++ ver 3.1 1 1 1 1 6666
// 04-20-94 1 .. 1 6 6
// 11111 .. 11111 666
////////////////////////////////////////////////////////////////////////
#include "au.hpp"
/*********************************************************************/
/* Define Statements */
/*********************/
#define PROGRAM "VERSION" // Name of module
/*********************************************************************/
#define SZ_SEARCH_STRING 13
#define NUM_ELS 30
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
class VER_WEIGHTS_INFO
{
private:
struct WEIGHT
{
char version[SZ_SEARCH_STRING];
long weight;
};
int maxWeights;
int numWeights;
WEIGHT *w;
void SharedInit()
{
numWeights = 0;
w = new WEIGHT[maxWeights];
}
BOOLEAN RemoveSmallest(long);
public:
VER_WEIGHTS_INFO(int x)
{
maxWeights = x;
SharedInit();
}
VER_WEIGHTS_INFO()
{
maxWeights = 20;
SharedInit();
}
~VER_WEIGHTS_INFO()
{
delete w;
}
void add(char *, long);
void find_largest(char *);
void display(AU *);
};
class WEIGHT_FILE
{
public:
int pos;
char file_name[NUM_ELS][SZ_SEARCH_STRING];
int weight[NUM_ELS];
WEIGHT_FILE()
{
pos = 0;
}
void add(char *str, int w)
{
if (pos < NUM_ELS)
{
safe_string_copy(file_name[pos], str, SZ_SEARCH_STRING, TRUE);
weight[pos] = w;
pos++;
}
}
};
class WEIGHT_STRING
{
public:
int pos;
char string[NUM_ELS][SZ_SEARCH_STRING];
int weight[NUM_ELS];
int len[NUM_ELS];
WEIGHT_STRING()
{
pos = 0;
}
void add(char *str, int w)
{
if (pos < NUM_ELS)
{
safe_string_copy(string[pos], str, SZ_SEARCH_STRING, TRUE);
len[pos] = strlen(str);
weight[pos] = w;
pos++;
}
}
};
typedef struct
{
WEIGHT_FILE weight_file;
WEIGHT_STRING weight_string;
char used_as_first[26];
char show_all;
int number;
} VERSION_INFO;
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
BOOLEAN VER_WEIGHTS_INFO::RemoveSmallest(long weight)
{
long smallest = 999999999;
int smallestPos = 0;
/* -3 give the last 3 a chance to mature before being wiped */
for (int i=0; i < numWeights-3; i++)
{
if (w[i].weight < smallest)
{
smallestPos = i;
smallest = w[i].weight;
}
}
if (smallest > weight)
return FALSE;
/* Slide them */
memmove(&w[smallestPos], &w[smallestPos+1],
sizeof(WEIGHT) * (numWeights - smallestPos - 1));
numWeights--;
return TRUE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
void VER_WEIGHTS_INFO::find_largest(char *buffer)
{
long largest = 0;
int largestPos = 0;
if (numWeights == 0)
{
buffer[0] = '\0';
return;
}
for (int i=0; i < numWeights; i++)
{
if (w[i].weight > largest)
{
largestPos = i;
largest = w[i].weight;
}
}
strcpy(buffer, w[largestPos].version);
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
void VER_WEIGHTS_INFO::display(AU *au)
{
au_printf(au, "\n");
for (int i=0; i < numWeights; i++)
{
au_printf(au, "%*s %8ld ", SZ_SEARCH_STRING, w[i].version,
w[i].weight);
if (i % 3 == 2)
au_printf(au, "\n");
}
au_printf(au, "\n");
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
void VER_WEIGHTS_INFO::add(char *ver, long weight)
{
if (weight == 0)
return;
for (int i=0; i < numWeights; i++)
{
if (stricmp(ver, w[i].version) == 0)
{
w[i].weight += weight;
return;
}
}
if (i == maxWeights)
{
if (RemoveSmallest(weight))
{
i--;
w[i].weight = 0;
}
else
return;
}
else
{
w[numWeights].weight = 0;
}
numWeights++;
strcpy(w[i].version, ver);
w[i].weight += weight;
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int get_file_weight(AU *au, char *file_name)
{
VERSION_INFO *in = (VERSION_INFO *)au->info;
int i;
for (i=0; i < in->weight_file.pos; i++)
{
if (wildcard_compare(au, file_name, in->weight_file.file_name[i]))
return in->weight_file.weight[i];
}
return 100;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int find_match(AU *au, char *buffer, long *pos)
{
VERSION_INFO *in = (VERSION_INFO *)au->info;
int i;
/* Case sensitive search */
for (i = 0; i < in->weight_string.pos; i++)
{
if (strncmp(in->weight_string.string[i], buffer,
in->weight_string.len[i]) == 0)
{
*pos += in->weight_string.len[i];
return in->weight_string.weight[i];
}
}
/* Case insensitive search, weight is half the amount */
for (i = 0; i < in->weight_string.pos; i++)
{
if (strnicmp(in->weight_string.string[i], buffer,
in->weight_string.len[i]) == 0)
{
*pos += in->weight_string.len[i];
return in->weight_string.weight[i] / 2;
}
}
return -1;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int IsAlpha(int c)
{
return (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z');
}
static int IsDigit(int c)
{
return (c >= '0' && c <= '9');
}
static int IsSpace(int c)
{
return (c >=0x09 && c <= 0x0d || c == 0x20 || c == 0x00);
}
static int IsPunct(int c)
{
return (strchr(".,:;", c) != NULL);
}
static int is_alpha_ver_char(int c)
{
return (IsAlpha(c) || c == 0xE0 || c == 0xE1);
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
/* Modifiers
- Base value 100.
- If no decimal, then value = size of version string, if over 4 then value =1
- if version string starts with a decimal /4
- if version string contains more than one alpha characters then / (x*x)
where x = number of alpha character found.
- if version string contains more than one decimal point, then / x
where x = number of decimal points
- if version string length > 7 then / (length - 5)
- for each alpha.alpha appears then /2
- for each .alpha appears then /2 (so alpha.alpha is really worth a /4)
- for each alpha digit alpha appears then /3
*/
static BOOLEAN get_version_string(char *version_string, char *buffer, int len,
int *value, long *pos)
{
int i=0;
int ch;
int vp = 0;
int is_digit;
int no_alpha = 0;
int no_dec = 0;
int alpha_dot_alpha = 0;
int dot_alpha = 0;
int digit_found = 0;
int alpha_digit_alpha = 0;
while (IsSpace(buffer[i]) && i < len)
i++;
if (i < len)
{
ch = buffer[i];
is_digit = IsDigit(ch);
if (is_digit || ch == '.')
{
for (;;)
{
ch = buffer[i];
is_digit = IsDigit(ch);
while ((is_digit || ch == '.') && i < len)
{
if (is_digit)
digit_found = TRUE;
else
no_dec++;
version_string[vp++] = ch;
i++;
if (ch == '.' && buffer[i] == '.')
break;
ch = buffer[i];
is_digit = IsDigit(ch);
}
if (i < len)
{
if (is_alpha_ver_char(ch) &&
!is_alpha_ver_char(buffer[i+1]))
{
no_alpha++;
if (version_string[vp-1] == '.')
{
dot_alpha++;
if (vp > 1 &&
is_alpha_ver_char(version_string[vp-2]))
{
alpha_dot_alpha++;
}
}
else if (vp > 1 &&
IsDigit(version_string[vp-1]) &&
is_alpha_ver_char(version_string[vp-2]))
{
alpha_digit_alpha++;
}
version_string[vp++] = ch;
i++;
continue;
}
}
break;
}
if (!digit_found)
return FALSE;
if (version_string[vp-1] == '.')
{
vp--;
i--;
no_dec--;
if (vp == 0)
return FALSE;
}
version_string[vp] = '\0';
/* Ignore version 0 */
if (strcmp(version_string, "0") == 0 ||
strcmp(version_string, ".0") == 0 ||
strcmp(version_string, ".00") == 0 ||
strncmp(version_string, ".0.", 3) == 0)
{
return FALSE;
}
else if (no_dec == 0)
{
/* Avoid things like 9A */
ch = version_string[vp-1];
if (!IsDigit(ch) && !IsPunct(ch))
return FALSE;
if (vp < 4)
*value = vp;
else
*value = 1;
}
else
{
*value = 100;
/* First character is a . */
if (version_string[0] == '.')
*value /= 4;
if (no_alpha > 0)
*value /= (no_alpha * no_alpha);
if (no_dec > 0)
*value /= no_dec;
if (vp > 7)
*value /= (vp - 5);
if (alpha_dot_alpha > 0)
*value /= (2 * alpha_dot_alpha);
if (dot_alpha > 0)
*value /= (2 * dot_alpha);
if (alpha_digit_alpha > 0)
*value /= (3 * alpha_digit_alpha);
}
*pos += i;
return TRUE;
}
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static STATUS process_file(AU *au, char *file_name, int weight,
VER_WEIGHTS_INFO *weights_info)
{
VERSION_INFO *in = (VERSION_INFO *)au->info;
HANDLE handle(16384);
char version_string[SZ_SEARCH_STRING+1];
char buffer[SZ_SEARCH_STRING+1];
int prev_ch;
long pos;
int len;
int val;
int i;
int ch = ' ';
if (handle.open(au, file_name, O_RDONLY | O_BINARY) != SUCCESS)
return FAILURE;
pos = 0;
for (EVER)
{
handle.seek(pos, SEEK_SET);
prev_ch = ch;
ch = handle.read_char();
if (ch == EOF)
break;
if (!IsDigit(ch) && ch != '.' &&
strchr(in->used_as_first, toupper(ch)) == NULL)
{
pos++;
continue;
}
buffer[0] = ch;
len = handle.read(buffer+1, sizeof(buffer)-2);
buffer[len] = '\0';
if ((i = find_match(au, buffer, &pos)) != -1)
{
if (!IsSpace(prev_ch) && !IsPunct(prev_ch))
i /= 10;
handle.seek(pos, SEEK_SET);
if (handle.read(buffer, sizeof(buffer)-2) == 0)
break;
if (get_version_string(version_string, buffer, len, &val, &pos))
weights_info->add(version_string, (long)weight * i);
}
else if (get_version_string(version_string, buffer, len, &val, &pos))
{
/* Weight it less if character immediately before the number
is not whitespace of punctuation */
if (IsSpace(prev_ch))
val = (val * 3) / 2;
else if (IsPunct(prev_ch))
val /= 2;
else
val /= 3;
if ((long)weight * (long)val > 0 && strlen(version_string) > 1)
weights_info->add(version_string, (long)weight * (long)val);
}
else
pos++;
}
handle.close();
return SUCCESS;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int version_one_file(AU *au, char *file_name, char *ver_string)
{
int weight;
VERSION_INFO *in = (VERSION_INFO *)au->info;
VER_WEIGHTS_INFO vwInfo(in->number);
weight = get_file_weight(au, file_name);
process_file(au, file_name, weight, &vwInfo);
if (in->show_all == ON)
vwInfo.display(au);
vwInfo.find_largest(ver_string);
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int version_archive(AU *au, ARC_HANDLE *, char *file_name, char *ver_string)
{
struct ffblk ffblk; // directory entry structure
char holdCurDir[FLENGTH];
char curDir[FLENGTH];
char destDir[FLENGTH];
LISTPTR paths;
int weight;
VERSION_INFO *in = (VERSION_INFO *)au->info;
VER_WEIGHTS_INFO vwInfo(in->number);
getcwd(curDir, FLENGTH);
build_fname(destDir, curDir, TEMP_DIR);
mkdir(TEMP_DIR);
unarc(au, file_name, destDir, &paths, 0, FALSE);
au_printf(au, "\n");
paths.add(destDir);
for (LIST *el = paths.head; el != NULL; el = el->next)
{
cd(au, el->data, NULL);
if (!findfirst("*.*", &ffblk, 0))
{
do
{
weight = get_file_weight(au, ffblk.ff_name);
process_file(au, ffblk.ff_name, weight, &vwInfo);
} while (!findnext(&ffblk));
}
}
if (in->show_all == ON)
vwInfo.display(au);
vwInfo.find_largest(ver_string);
clean_paths(au, &paths);
cd(au, curDir, NULL);
rmdir(TEMP_DIR);
cd(au, holdCurDir, NULL);
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int version(AU *au, char *file_name)
{
ARC_HANDLE arc_handle;
char ver_string[30];
check_for_key();
au->number_processed++;
arc_handle.init(au, file_name);
arc_handle.deinit(au);
if (arc_handle.type == 0)
version_one_file(au, file_name, ver_string);
else
version_archive(au, &arc_handle, file_name, ver_string);
au_printf(au, "@?1%*s@?H %s\n", FILE_SIZE, file_name, ver_string);
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void ReadCFGInfo(AU *au, CFG_HANDLE *cfg_handle)
{
char string[200],
string2[200],
string3[200];
VERSION_INFO *in = (VERSION_INFO *)au->info;
for(EVER)
{
if (cfg_handle->read_line(au, string) == EOF)
break;
split_string(string, string2);
split_string(string, string3);
if (string2[0] == '\0')
continue;
strcpy(au->curOpt, string2);
au->curVal = string3;
switch (toupper(string2[1]) << 8 | toupper(string2[0]))
{
case 'BE': // Begin
return;
case 'WE':
if (stricmp(string2, "WEIGHT_FILE") == 0)
in->weight_file.add(string3, atoi(string));
else
{
in->weight_string.add(string3, atoi(string));
if (strchr(in->used_as_first, toupper(string3[0])) == NULL)
{
int len;
len = strlen(in->used_as_first);
in->used_as_first[len] = toupper(string3[0]);
in->used_as_first[len+1] = '\0';
}
}
break;
default:
cfg_handle->invalid_option(au, string2);
}
}
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static BYTE parse_comm_line(AU *au, char option, char *cur_argv, PARSE_TYPE type)
{
VERSION_INFO *in = (VERSION_INFO *)au->info;
switch (type)
{
case PARSE_PARAM_OPTION:
switch (option)
{
case 'D':
in->show_all = get_value(au, OFF | ON);
break;
case 'N':
in->number = atoi(cur_argv);
break;
case '?':
au_standard_opt_header(au, "Version",
"@?3-D@?Hon|off Display full breakdown\n"
"@?3-N@?Hx Gather top x version strings\n");
exit (0);
default:
au_invalid_option(au, PROGRAM, option);
}
return TRUE;
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
int main_version(AU *au, int argc, char *argv[])
{
VERSION_INFO *in;
in = new VERSION_INFO;
memset(in, '\0', sizeof(VERSION_INFO));
in->number = 20;
au->info = in;
ReadGlobalCFGInfo(au, au->cfg_file, PROGRAM, ReadCFGInfo);
generic_parse_comm_line(au, argc, argv, parse_comm_line);
au->unarc_paths = ON;
au->recurse = OFF; // uses a different style of recurse
process_files(au, version);
if (!au->no_extra)
au_printf_c(au, 15, "\n\nFiles Processed = %d\n", au->number_processed);
return 0;
}